package cn.tml.innermost.service.Impl;

import cn.tml.innermost.user.config.RecommendProperties;
import cn.tml.innermost.feign.MusicService;
import cn.tml.innermost.framework.entity.vo.ResultMessage;
import cn.tml.innermost.framework.security.context.UserContext;
import cn.tml.innermost.music.params.SelectMusicWithKeyParams;
import cn.tml.innermost.music.vo.MusicInfoVO;
import cn.tml.innermost.music.vo.MusicListInfoVO;
import cn.tml.innermost.recommend.dos.UserFeature;
import cn.tml.innermost.service.RecommendService;
import cn.tml.innermost.user.vos.params.PageParams;
import cn.tml.innermost.user.dos.MusicRecord;
import cn.tml.innermost.feign.UserService;
import cn.tml.innermost.mapper.UserFeatureMapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
public class RecommendServiceImpl implements RecommendService {
    @Resource
    UserService userService;
    @Resource
    MusicService musicService;
    @Resource
    RecommendProperties recommendProperties;
    @Resource
    UserFeatureMapper userFeatureMapper;

    /**
     * 基于物品的协同过滤，通过用户播放历史找出音乐类型，音乐语言，歌手，进行相似推荐
     * @param
     * @param musicNum
     * @return
     */
    @Override
    public List<MusicInfoVO> getRecommendSongs(Integer musicNum) {

        List<MusicInfoVO> recommendSongs = new ArrayList<>();
        Long userId = UserContext.getCurrentUser().getId();
        PageParams pageParams = new PageParams(1,50);
//        获取用户的播放历史
        ResultMessage<List<MusicRecord>> result1 = userService.playingRecord(pageParams);
        List<MusicRecord> data1 = result1.getResult();
        List<Long> musicId = new ArrayList<>();
        for (MusicRecord record : data1) {
            musicId.add(record.getMusicId());
        }
//        获取music实体类
        ResultMessage<List<MusicInfoVO>> result2 = musicService.selectMusicList(musicId);
        List<MusicInfoVO> data2 = result2.getResult();
        Set<String> musicType = new HashSet<>();
        Set<String> musicLanguage = new HashSet<>();
        Set<String> musicSinger = new HashSet<>();
        for (MusicInfoVO musicInfoVO : data2) {
            musicType.add(musicInfoVO.getGenres());
            musicLanguage.add(musicInfoVO.getLanguages());
            musicSinger.add(musicInfoVO.getSingerName());
        }
        SelectMusicWithKeyParams params = new SelectMusicWithKeyParams();
//        每种最多请求10个
        int time = 10;
        if(musicType.size()>0){
            int perSameTypeNums = recommendProperties.sameGenresCount/musicType.size() ;
            params.setColumn("genres");
            params.setNums(perSameTypeNums>0?perSameTypeNums:1);
            for (String value : musicType) {
                params.setValue(value);
                List<MusicInfoVO> result = musicService.selectMusicListWithColumn(params).getResult();
                recommendSongs.addAll(result);
                time--;
                if(time == 0){
                    break;
                }
            }

        }
        time = 10;
        if (musicSinger.size()>0) {
            int perSameSingerNums = recommendProperties.sameSingerCount/musicSinger.size();
            params.setColumn("singer_name");
            params.setNums(perSameSingerNums>0?perSameSingerNums:1);
            for (String value : musicSinger) {
                params.setValue(value);
                List<MusicInfoVO> result = musicService.selectMusicListWithColumn(params).getResult();
                recommendSongs.addAll(result);
                time--;
                if(time == 0){
                    break;
                }
            }
        }
        time = 10;
        if (musicLanguage.size()>0) {
            int perSameLanguageNums = recommendProperties.sameLanguageCount/musicLanguage.size();
            params.setColumn("languages");
            params.setNums(perSameLanguageNums>0?perSameLanguageNums:1);
            for (String value : musicSinger) {
                params.setValue(value);
                List<MusicInfoVO> result = musicService.selectMusicListWithColumn(params).getResult();
                recommendSongs.addAll(result);
                time--;
                if(time == 0){
                    break;
                }
            }
        }
//        进行保存用户特征
        this.saveUserFeature(musicType,"genres",userId);
        this.saveUserFeature(musicSinger,"singer_name",userId);
        this.saveUserFeature(musicType,"languages",userId);

        return recommendSongs;
    }

    @Override
    public List<MusicListInfoVO> getRecommendMusicList(Long userId, Integer musicListNum) {
        return null;
    }

    private void saveUserFeature(Set<String> featureValue,String featureName,Long userId){
        UserFeature userFeature = new UserFeature();
        userFeature.setUserId(userId);
        userFeature.setFeatureName(featureName);
        for (String value : featureValue) {
            userFeature.setValue(value);
            userFeatureMapper.insert(userFeature);
        }
    }
}
